<?
##########################################################################
#		DOCUMENTATION
##########################################################################
# Main class from which derive all the classes that deal with HTML 
# visualization. It gives only the main functions common to every page
#
# Please add new features to derived classes, not here if they are not common
# functions in multiple pages
#
# © LiberLab group, 2011
##########################################################################

# on ubuntu: sudo apt-get install php5-tidy

class Root {
	# the variables doesn't have the static because there should be only on of these classes
	# running at one time.
	protected $language = "italian"; 
	protected $imagePath = "../covers/"; 
	private $startTime; protected $pageFile; protected $messages = array(); protected $tagHash;
	protected $delRegex; protected $scriptName; protected $staticDir; protected $baseScript;
	protected $defaultScriptName = "view.php";
	public function __construct($pageFile = "standard", $scriptName = "view", $delRegex = "") {
		# scriptName => name of the script that's calling this class (usually upload or view)
		# baseScript => name of the script that handle the ~90% of the site all the site (usually view.php)
		require_once("generalFunctions.php");
		require_once("config/messages.php");
		require_once("config/config.php");
		$var = new config(); $conf = $var->conf;
		$this->defaultScriptName = $conf['baseScript'];
		$this->cookiePrefix = $conf['cookiePrefix'];
		# init the startTime
		$this->startTime = mytimestamp();
		
		# load the default messages of the script given
		if (isset($messages[$this->language][$scriptName])){
			$this->messages = $messages[$this->language][$scriptName];
			if ($scriptName == "view"){
				$this->messages["topViewedBoxWithCat"] = str_replace("__cat__", $this->messages["catBox"], $this->messages["topViewedBoxBase"]);
				$this->messages["topViewedBoxWithoutCat"] = str_replace("__cat__", "", $this->messages["topViewedBoxBase"]);
			}
		}
		if (isset($messages[$this->language]["shared"])){
			$this->messages = array_merge($this->messages, $messages[$this->language]["shared"]);
		}
		$this->tagHash = array();
		$this->delRegex = $delRegex;
		$this->scriptName = $scriptName;
		$this->staticDir = fromCurrentDir("../../static/");
		if (!stristr(".htm", $pageFile)){ $pageFile = "$pageFile.html";}
		$this->pageFile = $pageFile;
		
		$this->startId = getParam("startid", 0);
		$this->limit = getParam("limit", 5);
		$this->selected = getParam("id", 0);
		
	}
	
	public function getCover($id, $extension){
		return "../{$this->imagePath}{$id}/cover." . $extension;
	}
	
	public function getCookie($param){
		if (isset($_COOKIE[$this->cookiePrefix . "_" . $param])){
			return $_COOKIE[$this->cookiePrefix . "_" . $param];
		}else{
			return null;	
		}	
	}
	
	public function getSession($param){
		if (isset($_SESSION[$param])){
			return $_SESSION[$param];
		}else{
			return null;
		}		
	}
	
	public function setSessionArray($array){
		$_SESSION = array_merge($_SESSION, $array);
	}
	
	public function setSession($param, $value){
		$_SESSION[$param] = $value;
	}
	
	public function delSession($param){
		unset($_SESSION[$param]);
	}
	
	public function delCookie($param){
		setcookie($this->cookiePrefix . "_" . $param,'', time()-800000);
	}
	
	public function setCookie($param, $value, $expire=1000000){
		setcookie($this->cookiePrefix . "_" . $param, $value, time()+$expire);
	}
	
	public function redirect($url){
		Header("Location: $url");
	}	
	
	public function orderHTML($html){
		# use tidy to order HTML ouput
		# Specify configuration
		$config = array(
				   'indent'         => true,
				   'output-xhtml'   => true,
				   'wrap'           => 200,
				   'doctype'	  => 'strict',);

		# Tidy
		$tidy = new tidy;
		$tidy->parseString($html, $config, 'utf8');
		$tidy->cleanRepair();

		#Output
		return $tidy;
	}
	
	public function checkAccess(){
		# check if the user is logged
		$nickname = $this->getSession("nickname");
		if ($nickname){
			return 1;
		}else{
			return 0;
		}		
	}
	
	public function mailCheck($email){
		# check the mail
		$emailMach = "/.+?@.+?\..+?/";
		if (preg_match($emailMach, $email)){
			return 1;
		}else{
			return 0;
		}
	}
	
	public function backOff(){
		# redirect to back off page
		return $this->redirect($this->defaultScriptName . "?language=" . $this->language . "&page=backoff");
	}
	
	public function isInHash($singleKeys, $index){
		$this->tagHash = $this->tagHash;
		for ($innerIndex = 0; $innerIndex<count($singleKeys); $innerIndex++){
			# delete the last 5 chars (valueINDEX -> value)
			$singleKey = substr($singleKeys[$innerIndex], 0, strlen($singleKeys[$innerIndex]) - 5);
			# if value with the index given is in the array, or the same without the last 5 chars
			# the "0" in needed because why are asking "is there at least one element in the sub-index?" if yes, expand!

			if (array_key_exists($singleKey . $index, $this->tagHash) || array_key_exists(substr($singleKey, 0, strlen($singleKey) - 5) . $index . "0", $this->tagHash)){
				return 1;
			}
		}
		return 0;
	}
	
	public function render($pageFile = NULL){
		# do the magic: turns static pages into dynamic ones, simply with text replacing
		require_once("dataStructure/category.php");
		if (!$pageFile){
			$pageFile = $this->pageFile;
		}else{
			$this->pageFile = $pageFile;
		}
		# get the HTML directory
		$staticDir = $this->staticDir; 
		$messages = $this->messages;
		
		# name of the base script, this will be used to replace every html link to this script
		$baseScript = $this->defaultScriptName;
		# in this version of the site, we have a fixed language.
		$language = $this->language; $this->tagHash["language"] = $language;
		$start = $this->startTime; $delRegex = $this->delRegex;

		$pageFileDir = $staticDir . $language . "/" . $pageFile;
		try{
			if ($pageFile == "404.html"){
				header("HTTP/1.0 404 Not Found");
			}
			$text = file_get_contents($pageFileDir);
		}catch (cantOpen $e){
			header("HTTP/1.0 404 Not Found");
			try{
				$text404 = file_get_contents($staticDir . "$language/404.html");
			}catch (cantOpen $e){
				$text404 = "<h1>404</h1><p>FATAL 404 Error: Can't open the page given.</p>";
			}
			$delRegex = "";
			$text = $text404; 
		}
		
		
		if (($this->getCookie("nickname") and $this->getCookie("password")) and !($this->getSession("nickname") and $this->getSession("password"))){
			require_once("dataStructure/user.php");
			$userClass = new User();
			$passwordEncrypted = $userClass->login($this->getCookie("nickname"), $this->getCookie("password"), true);

			if ($passwordEncrypted){
				$this->setSession("nickname", $this->getCookie("nickname"));
				$this->setSession("password", $passwordEncrypted);
			}
		}
		# expand header
		$this->tagHash["urlHeaderINDEX§§§§contentHeaderINDEX"] = 2; 
		if ($this->getSession("nickname") and $this->getSession("password")){
			$this->tagHash["urlHeader0"] = "profile.html";
			$this->tagHash["contentHeader0"] = ucfirst($this->getSession("nickname"));
			$this->tagHash["urlHeader1"] = "logout.php";
			$this->tagHash["contentHeader1"] = $messages["logout"];
		}else{
			$this->tagHash["urlHeader0"] = "login.html";
			$this->tagHash["contentHeader0"] = $messages["login"];	
			$this->tagHash["urlHeader1"] = "signin.html";
			$this->tagHash["contentHeader1"] = $messages["signin"];		
		}
		# IE fix
		$text = preg_replace("/<!-- *?__ieStart__ *?-->/", "<!--[if lte IE 7]>", $text);
		$text = preg_replace("/<!-- *?__ieEnd__ *?-->/", "<![endif]-->", $text);
		
		# expand categories in nav
		$categoryClass = new Category();
		$categories = $categoryClass->getCategoriesNum("books", true);

		$maxInd = min(count($categories), 5);
		$this->tagHash["categoryLinkINDEX§§§§categoryINDEX"] = $maxInd; 
		for($index=0; $index<$maxInd; $index++){
			$category = $categories[$index];
			$categoryId = $category->id;
			$categoryName = $category->category;
			$this->tagHash["categoryLink$index"] = "$baseScript?language=$language&amp;page=category&amp;id=$categoryId";
			$this->tagHash["category$index"] = ucfirst($categoryName);		
		}
		
		$this->tagHashKeys = array_keys($this->tagHash);
		# real rendering
		for($indexKey=0; $indexKey < count($this->tagHashKeys); $indexKey++){
			$key = $this->tagHashKeys[$indexKey];	
			if (stristr($key, "INDEX")){
				$maxInd = $this->tagHash[$key];
				unset($this->tagHash[$key]);
				$singleKeys = explode("§§§§", $key);
				$firstKey = $singleKeys[0];
				$startTag = '<!-- *?§§start *?-->';
				$endTag = '<!-- *?§§end *?-->';

				# build the regex that will parse the text
				$fromRegexBase = '\s*?([^§]*?' . "__$firstKey";
				for($index=1; $index<count($singleKeys); $index++){
					$singleKey = $singleKeys[$index];
					$fromRegexBase =  $fromRegexBase . '__[^§]*?(:?' . $startTag . '[^§]*?|)' . $singleKey . '(?:[^§]*?' . $endTag . '|)';
				}
				$fromRegexBase = $fromRegexBase . '[^§]*?)\s*?';
				$fromRegex = $startTag . $fromRegexBase . $endTag;
				preg_match("/$fromRegex/", $text, $results);
				$fromText = "";
				if ($results){
					$fromText = $results[1];
				}
				# build the regex to replace every somethingINDEX correctly
				for($index=0; $index<$maxInd; $index++){
					$temp = $fromText;
					$regex = "(";
					for($indexKeys=0; $indexKeys<count($singleKeys)-1; $indexKeys++){
						# deleting INDEX
						$singleKey = substr($singleKeys[$indexKeys], 0, strlen($singleKeys[$indexKeys]) - 5);
						$regex = $regex . $singleKey . "|";
					}
					
					$singleKey = substr($singleKeys[count($singleKeys)-1], 0, strlen($singleKeys[count($singleKeys)-1]) - 5); 
					$regex = $regex . $singleKey . ")INDEX";
					
					if ($this->isInHash($singleKeys, $index)){
						$stIndex = (string) $index;
						# do it all together didn't work.
						$temp = preg_replace("/$regex/", '$1§§TEMPIND§§', $temp);
						$temp = str_replace("§§TEMPIND§§", $index, $temp);
						
						$temp = preg_replace("/INDEX$index/", $index . "INDEX", $temp);
						$text = preg_replace("/$fromRegex/s", "$temp\n<!--§§start-->$fromText<!--§§end-->", $text);
					}
				}	
				$text = preg_replace("/$fromRegex/s", "", $text);
				
			}
		}
		# replace the normal string as __language__ -> italian
		$this->tagHashKeys = array_keys($this->tagHash);
		foreach ($this->tagHashKeys as $key){
			$replaceText = $this->tagHash[$key];
			$fromRegex = "__$key" . "__";
			$text = str_replace("$fromRegex", $replaceText, $text);
		}
		# used to delete the links that link the current page
		if ($delRegex){
			$text = preg_replace("/$delRegex/", "\\1", $text);
		}
		# replace every link to the page with the onlink class
		$text = preg_replace("/<([^>]*?)>\s*?<a[^>]*?href=\"[^\"]*?" . $this->pageFile . "[^>]*?>([^<]*?)<\/a>\s*?<\/([^>]*?)>/", 
		"<\\1 class=\"onlink\">\\2</\\1>", $text);
		
		# redirect every link to html pages into view.pl
		$text = preg_replace("/href=\"(?:[^\/][^\"]*?\/|)([^\/\"]+?)\.html\"/", "href=\"$baseScript?language=$language&amp;page=$1\"", $text);
		# link correctly css, javascript, images, etc.
		$regex = "(src|href)\s*?=\s*?\"([^\"]*?)\"";
		$newText = $text;
		preg_match_all("/$regex/", $text, $results);
		# do the redirecting
		for($index=0; $index<count($results[0]); $index++){
			$selector = $results[1][$index];
			$link = $results[2][$index];
			$newLink = str_replace("public_html/", "", $link);
			if ("../" == substr($newLink, 0, 3)){
				$newLink = cleanLink("null/$newLink");
			}
			$link = str_replace("/", "\/", $link);
			
			$newText = preg_replace("/$selector\s*?=\s*?\"$link\"/", "$selector=\"$newLink\"", $newText);
		}
		$text = $newText;
		# clean HTML from the __value__ that we aren't able to map correctly
		# no more needed (this code is in "perl mode", may turn useful)
		/*
		$text =~ s/(?:<[^<>\/]+?>\s*?)+?__[^_]*?__(?:\s*?<\/[^<>]+?>)+?//g;
		$text =~ s/<[^<>]+>\s*?<[^>*?]"\s*?__[^_]+?__\s*?"[^>*?]>\s*?<\/.+<>//g;
		$text =~ s/(?:<[^<>\/]+?>\s*?)*?<[^<>]*?"\s*?__[^_]+?__\s*?"[^<>]*?(?:\s*?<\/[^<>]+?>)*?>//g;
		$text =~ s/\s*?__[^_]+?__\s*?//g;
		*/
		# see how much time has been needed to load the page
		if ($start){
			$duration = mytimestamp($start);
			$duration = substr($duration, 0, 4);
			# change delimiter to prevent conflicts
			$text = preg_replace("/__duration__/", $duration, $text);
		}
		$text = $this->orderHTML($text);
		
		return $text;
		
	}

	public function __destruct() {
	}
};

?>
